From fb559c62129c6381ebd37fbf9d26bacd6be834c4 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 31 May 2005 08:27:49 +0000 Subject: [PATCH] bitkeeper revision 1.1602 (429c2005b_phBM8VV-zUAH99jBwhMw) Updated process.c for x86-64. Signed-off-by: Jun Nakajima --- .../arch/xen/x86_64/kernel/process.c | 64 +++++++++++++++---- 1 file changed, 52 insertions(+), 12 deletions(-) diff --git a/linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/process.c b/linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/process.c index 263176f6b5..99210e91cb 100644 --- a/linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/process.c +++ b/linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/process.c @@ -21,6 +21,7 @@ #include +#include #include #include #include @@ -84,28 +85,48 @@ void enable_hlt(void) EXPORT_SYMBOL(enable_hlt); /* XXX XEN doesn't use default_idle(), poll_idle(). Use xen_idle() instead. */ -extern int set_timeout_timer(void); +extern void stop_hz_timer(void); +extern void start_hz_timer(void); void xen_idle(void) { - int cpu; - local_irq_disable(); - cpu = smp_processor_id(); - if (rcu_pending(cpu)) - rcu_check_callbacks(cpu, 0); - if (need_resched()) { local_irq_enable(); - } else if (set_timeout_timer() == 0) { - /* NB. Blocking reenable events in a race-free manner. */ - HYPERVISOR_block(); } else { - local_irq_enable(); - HYPERVISOR_yield(); + stop_hz_timer(); + HYPERVISOR_block(); /* implicit local_irq_enable() */ + start_hz_timer(); } } +#ifdef CONFIG_HOTPLUG_CPU +#include +/* We don't actually take CPU down, just spin without interrupts. */ +static inline void play_dead(void) +{ + /* Ack it */ + __get_cpu_var(cpu_state) = CPU_DEAD; + + /* We shouldn't have to disable interrupts while dead, but + * some interrupts just don't seem to go away, and this makes + * it "work" for testing purposes. */ + /* Death loop */ + while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE) + HYPERVISOR_yield(); + + local_irq_disable(); + __flush_tlb_all(); + cpu_set(smp_processor_id(), cpu_online_map); + local_irq_enable(); +} +#else +static inline void play_dead(void) +{ + BUG(); +} +#endif /* CONFIG_HOTPLUG_CPU */ + /* * The idle thread. There's no useful work to be * done, so just try to conserve power and have a @@ -122,6 +143,9 @@ void cpu_idle (void) if (cpu_isset(cpu, cpu_idle_map)) cpu_clear(cpu, cpu_idle_map); rmb(); + + if (cpu_is_offline(cpu)) + play_dead(); __IRQ_STAT(cpu,idle_timestamp) = jiffies; xen_idle(); @@ -130,6 +154,22 @@ void cpu_idle (void) } } +void cpu_idle_wait(void) +{ + int cpu; + cpumask_t map; + + for_each_online_cpu(cpu) + cpu_set(cpu, cpu_idle_map); + + wmb(); + do { + ssleep(1); + cpus_and(map, cpu_idle_map, cpu_online_map); + } while (!cpus_empty(map)); +} +EXPORT_SYMBOL_GPL(cpu_idle_wait); + /* XXX XEN doesn't use mwait_idle(), select_idle_routine(), idle_setup(). */ /* Always use xen_idle() instead. */ void __init select_idle_routine(const struct cpuinfo_x86 *c) {} -- 2.30.2